<template>
  <el-select style="width: 100%" v-model="code" :value-key="valueFiled" :multiple="multiple" filterable :clearable="clearable" :placeholder="placeholder" :loading="loading" @change="onChange">
    <el-option v-for="(item, index) in opts" :key="index" :label="item[labelFiled]" :value="item[valueFiled]"></el-option>
  </el-select>
</template>

<script>
import request from '@/utils/request';
export default {
  name: 'SelectByApi',
  props: {
    /* 绑定值 */
    value: {
      type: [String, Number],
      default: null
    },
    /* 绑定名称 */
    label: {
      type: [String, Number],
      default: null
    },
    // 绑定值string转为number
    stringToNumber: {
      type: Boolean,
      default: false
    },
    // 占位提示
    placeholder: {
      type: String,
      default: '请选择'
    },
    // 是否多选，为true时，value值为逗号分割的字符串
    multiple: {
      type: Boolean,
      default: false
    },
    // 请求地址
    api: {
      type: [Function, String],
      required: false,
      default: null
    },
    // 请求参数
    params: {
      type: Object,
      default: null
    },
    // 显示字段
    labelFiled: {
      type: String,
      default: 'name'
    },
    // 绑定字段
    valueFiled: {
      type: String,
      default: 'id'
    },
    clearable: {
        type: Boolean,
        default: false
    },
    options: {
        type: [Array, null],
        default: null
    }
  },
  data() {
    return {
      loading: false,
      opts: [],
      isFirstFetch: true,
      code: null
    };
  },
  watch: {
    value: {
      handler(val) {
        this.isFirstFetch && this.fetch();
        if (!val) {
          this.code = null;
          return;
        }
        if (this.multiple) {
          this.code = this.stringToNumber ? val.split(',').map((t) => Number(t)) : val.split(',');
        } else {
          this.code = this.stringToNumber ? Number(val) : val;
        }
      },
      immediate: true
    },
    options: {
        handler(val) {
            this.opts = val || [];
        },
        immediate: true
    }
  },
  methods: {
    fetch() {
      this.isFirstFetch = false;
      if(this.options) return;
      this.opts = [];
      this.loading = true;
      if (typeof this.api === 'string' && this.api) {
        request({
          url: this.api,
          method: 'get',
          params: this.params
        })
          .then((res) => {
            this.loading = false;
            this.opts = res.data || [];
          })
          .catch((err) => {
            this.loading = false;
          });
      } else {
        this.api(this.params)
          .then((res) => {
            this.loading = false;
            this.opts = res.data || [];
          })
          .catch((err) => {
            this.loading = false;
          });
      }
    },
    onChange(e) {
      if (this.multiple) {
        this.$emit('input', e.join(','));
        this.$emit('change');
      } else {
        const item = this.opts.find((item) => item[this.valueFiled] == e);
        this.$emit('input', e);
        this.$emit('update:label', item ? item[this.labelFiled] : null);
        this.$emit('change', item || {});
      }
    }
  }
};
</script>
